/**
 * 通过crypto-js和jsencrypt实现[加解密/编解码/摘要]工具
 * AES、HASH(MD5、SHA256)、RSA、Base64
 * @author luwei
 * @version 1.0.0, 2019-03-16
 */
import CryptoJS from 'crypto-js'
import JSEncrypt from '@/util/jsencrypt.js'

const DEFAULT_AES_KEY = 'B7jUZMf9Y1xdOM6H'

/**
 * 使用AES算法(CBC/PKCS5Padding)加密
 * @param {string} text 待加密文本
 * @param {string} key 16字符长(128位)的加密密钥
 * @return string 密文
 */
const encryptByAES = (text, key = DEFAULT_AES_KEY) => {
  let keyAndIv = CryptoJS.enc.Utf8.parse(key)
  let ciphertext = CryptoJS.AES.encrypt(text, keyAndIv, {
    // iv使用key值
    iv: keyAndIv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  // 返回的是base64格式的密文
  return ciphertext.toString()
}

/**
 * 使用AES算法(CBC/PKCS5Padding)解密
 * @param {string} ciphertext 密文
 * @param {string} key 16字符长的加密密钥
 * @return string 明文
 */
const decryptByAES = (ciphertext, key = DEFAULT_AES_KEY) => {
  let keyAndIv = CryptoJS.enc.Utf8.parse(key)
  let bytes = CryptoJS.AES.decrypt(ciphertext, keyAndIv, {
    // iv使用key值
    iv: keyAndIv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  return bytes.toString(CryptoJS.enc.Utf8)
}

/**
 * 使用SHA256算法计算摘要
 */
const sha256 = text => {
  return CryptoJS.SHA256(text).toString()
}

/**
 * 使用MD5算法计算摘要
 */
const md5 = text => {
  return CryptoJS.MD5(text).toString()
}

/**
 * base64编码和解码
 */
const base64 = {
  /** 编码 */
  en: data => CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(data)),
  /** 解码 */
  de: data => CryptoJS.enc.Base64.parse(data).toString(CryptoJS.enc.Utf8)
}

/**
 * 获取一个新的16位字符长度(128位)的AES密钥
 */
const newAESKey = () => {
  return randomString(16)
}

/**
 * 获取随机字符串
 * @param {int} len 随机字符串长度, 默认16
 * @return {string} 随机字符串
 */
const randomString = (len = 16) => {
  // 默认去掉了容易混淆的字符oOLl,gq,Vv,Uu,I1
  let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz234567890'
  // $chars.length
  let maxPos = 48
  let str = ''
  for (let i = 0; i < len; i++) {
    str += $chars.charAt(Math.floor(Math.random() * maxPos))
  }
  return str
}

/** RSA公钥 */
const publicKeyOfRSA =
  'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGRYHMKF1FX5rz4qSt5AFbv+Cz' +
  'S9hzAf3kGbl2YCgS1l0iWIokpce3nhFAfSSu1mXbu5Dj2ZAemwxUNTLwVdybDhLj' +
  'awQo1GTH/WNcXTjBR2jqFWcreyKVWgQ06WCaugQMLppS9817cX+eZYt1P6o6idPL' +
  'DJzBNdT8gs41nfqd0wIDAQAB'

/**
 * 使用RSA算法加密,使用公钥加密
 * @param {string} text 待加密文本
 * @return string 密文
 */
const encryptByRSA = text => {
  let encrypt = new JSEncrypt()
  encrypt.setPublicKey(publicKeyOfRSA)
  return encrypt.encrypt(text)
}

/**
 * 使用RSA算法解密,使用私钥解密
 * 出于对私钥安全的考虑，暂不实现
 * @param {string} ciphertext 密文
 * @return string 明文
 */
const decryptByRSA = ciphertext => {
  // let decrypt = new JSEncrypt()
  // decrypt.setPrivateKey(privateKeyOfRSA)
  // return decrypt.decrypt(ciphertext)
  return ciphertext
}

export {
  encryptByAES,
  decryptByAES,
  sha256,
  md5,
  base64,
  newAESKey,
  encryptByRSA,
  decryptByRSA,
  randomString
}
